--[[
    desc: 魂石突破、洗练界面
    author:Hoo
    time:2022-01-05 14:56:52
]]

local itemBar = require 'View/CommonUI/ComResBar'

--- @class UIDebrisBaptism
local UIDebrisBaptism = UIBase.New(PanelResNames.UIDebrisBaptism)
local M = UIDebrisBaptism

--- 职业枚举
M.ProfessionEnum = {
    All     = 0,    -- 全部
    Recover = 1,    -- 恢复类
    Defense = 2,    -- 防守类
    Attack  = 3,    -- 进攻类
    Assist  = 4     -- 辅助类
}

--- 魂石类型筛选
--- @type number
local mProfessionTag = 0

--- 魂石品质筛选
--- @type number
local mQualityTag = 0

--- 魂石列表
--- @type any[]
local mItemList = {}

-- 属性列表
--- @type any[]
local mAttrList = {}

-- 突破技能列表
--- @type DebrisSubSkillProtoBean[]
local mSkillList = {}

-- 洗炼前技能列表
--- @type DebrisSubSkillProtoBean[]
local mPreSkillList = {}
-- 洗炼后技能列表
--- @type DebrisSubSkillProtoBean[]
local mNewSkillList = {}

--- 当前选择的魂石索引
--- @type number
local mSelectedIndex  = nil

--- 当前选择的魂石id
--- @type string
local mSelectedItemId = nil

--- 当前页面类型
--- @type number
local mViewType = nil

--- 消耗数据
--- @type number[]
local mCostData = nil

--- 魔力值最大值
--- @type number
local mMaxPower = nil

--- 进度条动画
--- @type boolean
local bBarAni = false

--- 点击事件时间戳（防连点）
--- @type number
local mClickTick   = 0
local mBaptizeTick = 0

function M.Init(viewType, itemId)
    mViewType = viewType
    mSelectedItemId = itemId
    UIBase.Init(M)
end

--- @protected
function M:OnCreate()
    self:RegisterOnClick(self:GetChild("btnBreak"),       self.onClickBroken,      self)
    self:RegisterOnClick(self:GetChild("btnBaptism"),     self.onClickBaptize,     self)
    self:RegisterOnClick(self:GetChild("btnTabBreak"),    self.onClickTabBroken,   self)
    self:RegisterOnClick(self:GetChild("btnTabBaptism"),  self.onClickTabBaptize,  self)
    self:RegisterOnClick(self:GetChild("btnAutoBaptism"), self.onClickAutoBaptize, self)
    self:RegisterOnClick(self:GetChild("btnSure"),        self.onClickEnsure,      self)
    self:RegisterOnClick(self:GetChild("btnCancel"),      self.onClickCancel,      self)
    self:RegisterOnClick(self:GetChild("btnReset"),       self.onClickReset,       self)
    self:RegisterOnClick(self:GetChild("btnLR"),          self.onClickBtnLR,       self)
    self:RegisterOnClick(self:GetChild("btnLRPlus"),      self.onClickBtnLRPlus,   self)
    self:RegisterOnClick(self:GetChild("btnProbability"), self.onClickRatio,       self)
    self:RegisterOnClick(self:GetChild("help"),           self.onClickHelp,        self)
    self:RegisterOnClick(self:GetChild("btnBack"),        self.onClickClose,       self)
    self:RegisterOnClick(self:GetChild("bgClose"),        self.onClickClose,       self)

    self.btnBroken        = self:GetChild("btnBreak")
    self.btnBaptism       = self:GetChild("btnBaptism")
    self.txtComNothing    = self:GetChild("Combo_Nothing/title")
    self.effBrokenGo      = self:GetChild("eff_shengjie_01")
    self.effBaptismGo     = self:GetChild("eff_shengjie_02")
    self.ctrlType         = self:GetController("type")
    self.ctrlBreakState   = self:GetController("BreakState")
    self.ctrlBaptismState = self:GetController("BaptismState")
    self.ctrlNothing      = self:GetController("nothing")
    self.aniSave          = self:GetTransition("save")
    self.aniCancel        = self:GetTransition("cancel")
    -- self.aniBaptism       = self:GetTransition("baptism")
    self.aniReset         = self:GetTransition("reset")

    -- 魂石列表
    self.listStone = self:GetChild("content")
    self:SetDynamicList(self.listStone, self.stoneItemRenderer, self)
    -- 属性列表
    self.listAttr = self:GetChild("attrList")
    self:SetDynamicList(self.listAttr, self.attrItemRenderer, self, true)
    -- 突破技能列表
    self.listSkill = self:GetChild("skillList")
    self:SetDynamicList(self.listSkill, self.skillItemRenderer, self, true)
    -- 洗炼前技能列表
    self.listPreSkill = self:GetChild("skillList1")
    self:SetDynamicList(self.listPreSkill, self.preSkillItemRenderer, self, true)
    -- 洗炼后技能列表
    self.listNewSkill = self:GetChild("skillList2")
    self:SetDynamicList(self.listNewSkill, self.newSkillItemRenderer, self, true)

    -- 展示区魂石
    self.debrisItem = self:GetChild("Debris")
    self.txtName    = self:GetChild("name")
    -- 物品消耗
    self.costItem = self:CreateComponent(itemBar, self:GetChild("currency"))
    -- 魔力值
    self.barPower = self:GetChild("barPower")
    self.txtBar   = self.barPower:GetChild("num")

    -- 筛选按钮
    self.professionbtns = {}
    local btn = nil
    for i = 0, 4 do
        btn = self:GetChild("btn" .. i)
        btn.onChanged:Add(function() self:onTabProfessionChanged(i) end, self)
        table.insert(self.professionbtns, btn)
    end

    self:GetChild("bgBreak/title").text       = getLanguage("DebrisText1")
    self:GetChild("btnBreak").title           = getLanguage("DebrisText1")
    self:GetChild("btnTabBreak").title        = getLanguage("DebrisText1")
    self:GetChild("bgBaptism/title").text     = getLanguage("DebrisText2")
    self:GetChild("btnBaptism").title         = getLanguage("DebrisText2")
    self:GetChild("btnTabBaptism").title      = getLanguage("DebrisText2")
    self:GetChild("btnProbability").title     = getLanguage("DebrisText3")
    self:GetChild("BaptismTips1").text        = getLanguage("DebrisText4")
    self:GetChild("textPower").text           = getLanguage("DebrisText5")
    self:GetChild("textPowerTips").text       = getLanguage("DebrisText6")
    self:GetChild("text1").text               = getLanguage("DebrisText7")
    self:GetChild("text2").text               = getLanguage("DebrisText8")
    self:GetChild("btnSure").title            = getLanguage("DebrisText9")
    self:GetChild("btnCancel").title          = getLanguage("DebrisText10")
    self:GetChild("Combo_Nothing/title").text = getLanguage("DebrisText13")

    ListenEvent(Config.EventType.DebrisBrokenRet,      self.resBrokenData,      self)
    ListenEvent(Config.EventType.DebrisBaptimsRet,     self.resBaptimsData,     self)
    ListenEvent(Config.EventType.DebrisAutoBaptimsRet, self.resAutoBaptimsData, self)
    ListenEvent(Config.EventType.DebirsBapReplaceRet , self.resReplaceSkill,    self)
    ListenEvent(Config.EventType.DebrisMagicValueRet , self.resMagicValue,      self)
end
--- @protected
function M:OnEnable()
    mClickTick      = 0
    mMaxPower       = tonumber(GetGlobalStringValue(656, true)[2] or 100)
    mViewType       = mViewType or self:checkViewState()

    self:refreshData()
    self:refreshView()
    self:reqMagicValue()
end
--- @protected
function M:OnDisable()
end
--- @protected
function M:OnDestroy()
    mClickTick      = nil
    mCostData       = nil
    mItemList       = nil
    mAttrList       = nil
    mSkillList      = nil
    mPreSkillList   = nil
    mNewSkillList   = nil
    mSelectedIndex  = nil
    mSelectedItemId = nil

    for i,v in ipairs(self.professionbtns) do
        v.onChanged:Clear()
    end
    self.professionbtns = nil

    self.effBrokenWrapper = nil
    if self.effBroken ~= nil then
        destroyImmediate(self.effBroken);
        self.effBroken = nil
    end

    self.effBaptismWrapper = nil
    if self.effBaptism ~= nil then
        destroyImmediate(self.effBaptism);
        self.effBaptism = nil
    end

    if self.timerId ~= nil then
        utimer.remove(self.timerId)
        self.timerId = nil
    end

    CloseEvent(Config.EventType.DebrisBrokenRet,      self.resBrokenData,      self)
    CloseEvent(Config.EventType.DebrisBaptimsRet,     self.resBaptimsData,     self)
    CloseEvent(Config.EventType.DebrisAutoBaptimsRet, self.resAutoBaptimsData, self)
    CloseEvent(Config.EventType.DebirsBapReplaceRet , self.resReplaceSkill,    self)
    CloseEvent(Config.EventType.DebrisMagicValueRet , self.resMagicValue,      self)
end

--- desc: 检测界面类型（突破 or 炼化）
--- @private
--- @return number
function M:checkViewState()
    local list = StrangeFragmentManager.FragmentInfoList
    if not list then
        return EnumConst.DebrisViewType.Broken
    end
    for k, v in pairs(list) do
        if v.quality == EnumConst.DebrisQuality.Dark then
            return EnumConst.DebrisViewType.Baptize
        end
    end
    return EnumConst.DebrisViewType.Broken
end

--- 消耗数据相关
--- @private
--- @return number[]
function M:parseCostData()
    if mViewType == EnumConst.DebrisViewType.Broken then
        return decodeJsonStrToTabel(dataTable.getGlobalString(631))
    else
        return decodeJsonStrToTabel(dataTable.getGlobalString(632))
    end
end

--- 检测技能里是否有高级属性
--- @private
--- @param skills DebrisSubSkillProtoBean[] 技能组
--- @return boolean
function M:checkHigherSkill(skills)
    if not skills then
        return false
    end

    for _, data in ipairs(skills) do
        local id, value = data.skillId, data.val
        if self:isHighLevel(id, value) then
            return true
        end
    end
    return false
end
--- 检测技能是否未高级技能
--- @private
--- @param id    number 技能id
--- @param value number 技能数值
--- @return boolean
function M:isHighLevel(id, value)
    local cfg = dataTable.getDataTableByStringId("t_debrisminorskill", tostring(id))
    if cfg and math.abs(value) >= math.abs(cfg.f_RareValue) then
        return true
    end
    return false
end

--- 获取魂石列表
--- @private
--- @param type    number 魂石类型
--- @param quality number 魂石品质
--- @return any[]
function M:getItemListData(type, quality)
    local list = {}
    if type and type ~= M.ProfessionEnum.All then
        list = StrangeFragmentManager.FilterProfession(type, quality)
    else
        list = StrangeFragmentManager.FilterQuality(quality)
    end

    table.sort(list, function(v1, v2)
        if v1.quality ~= v2.quality then
            return v1.quality > v2.quality
        else
            if v1.level ~= v2.level then
                return v1.level > v2.level
            end
        end
        return tonumber(v1.itemModelId) > tonumber(v2.itemModelId)
    end)
    return list
end
--- 获取选中魂石的索引
---@return number 索引
function M:checkSelectedIndex()
    if not mSelectedItemId then
        return 0
    end

    for i = 1, #mItemList do
        local data = mItemList[i]
        if mSelectedItemId == data.itemId then
            return i
        end
    end
    return 0
end

--- 刷新界面数据
--- @private
function M:refreshData()
    mCostData       = self:parseCostData()
    mQualityTag     = mViewType == EnumConst.DebrisViewType.Baptize and EnumConst.DebrisQuality.Dark or EnumConst.DebrisQuality.Immortal
    mProfessionTag  = M.ProfessionEnum.All
end

--- 刷新界面UI
--- @private
function M:refreshView()
    self.ctrlType.selectedIndex = mViewType
    self.ctrlBreakState.selectedIndex   = 0
    self.ctrlBaptismState.selectedIndex = 0
    self.listStone:ScrollToView(0, false)
    for i, v in ipairs(self.professionbtns) do
        v.selected = (i - 1 == mProfessionTag) and true or false
    end

    -- tip
    local tempStr = mViewType == EnumConst.DebrisViewType.Broken and "DebrisText11" or "DebrisText12"
    self.txtComNothing.text = getLanguage(tempStr)

    self:showItemDataUI(nil)
    self:loadStoneList()
    self:refreshCostUI()
end

--- 魂石列表
--- @private
function M:loadStoneList()
    mItemList = self:getItemListData(mProfessionTag, mQualityTag)
    mSelectedIndex = self:checkSelectedIndex()

    local cnt = #mItemList
    self.listStone.numItems = cnt
    self.ctrlNothing.selectedIndex = cnt == 0 and 1 or 0

    -- 自动定位
    if mSelectedIndex and mSelectedIndex > 0 then
        self.listStone:ScrollToView(mSelectedIndex - 1, false)
    end
end

-- 突破、洗炼消耗
function M:refreshCostUI()
    local btnObj
    if mViewType == EnumConst.DebrisViewType.Broken then
        btnObj = self.btnBroken
    else
        btnObj = self.btnBaptism
    end
    
    local costId, costNum = mCostData[1], mCostData[2]
    local currNum = logicMgr.ItemManager.getItemCountbyModelId(costId)
    local txtNum  = btnObj:GetChild("num")
    local imgIcon = btnObj:GetChild("Image")
    local costNumStr = tostring(costNum)
    if currNum < costNum then
        costNumStr = string.TextColor(costNumStr, "#FF0000");
    end

    txtNum.text = costNumStr
    imgIcon.url = EnumConst.AtlasPath.ItemAtlas .. logicMgr.ItemManager.GetItemIcon(costId)
    self.costItem:SetData(tonumber(costId))
end

--- 主魂石数据展示
--- @param itemData any 魂石数据
function M:showItemDataUI(itemData)
    if mViewType == EnumConst.DebrisViewType.Broken then
        self:showBrokenUI(itemData)
    else
        self:showBaptismUI(itemData)
    end
end
--- 主UI：突破
--- @param itemData any 魂石数据
function M:showBrokenUI(itemData)
    if itemData == nil then
        self.listAttr.numItems  = 0
        self.listSkill.numItems = 0
        self.txtName.text = ""
        self.ctrlBreakState.selectedIndex = 0
        return
    end

    -- 魂石
    self.ctrlBreakState.selectedIndex = 1
    self:refreshMainItem(itemData)
    
    -- 等级上限、属性值
    local currMaxLevel = self:getMaxLevelByDebrisId(itemData.itemModelId)
    local nextMaxLevel = self:getNextDebrisAttr(tostring(itemData.itemModelId), itemData.level, 0)
    mAttrList = {{0, currMaxLevel, nextMaxLevel}}
    local attr = itemData.GetAttr()
    for i, v in ipairs(attr) do
        local nextValue = self:getNextDebrisAttr(tostring(itemData.itemModelId), itemData.level, v[1])
        v[3] = nextValue
        table.insert(mAttrList, v)
    end
    self.listAttr.numItems = #mAttrList

    -- 技能
    mSkillList = {{index = 0, skillId = 0, val = 0}}
    self.listSkill.numItems = #mSkillList
end
--- 主UI：炼化
--- @param itemData any 魂石数据
function M:showBaptismUI(itemData)
    if itemData == nil then
        self.listPreSkill.numItems = 0
        self.listNewSkill.numItems = 0
        self.txtName.text = ""
        self.ctrlBaptismState.selectedIndex = 0
        return
    end

    -- 魂石
    self:refreshMainItem(itemData)

    -- 技能
    mPreSkillList = itemData.subSkills
    mNewSkillList = itemData.tempSkills or {}
    self:refreshBaptizeSkill()
end

--- 主魂石icon展示
--- @private
--- @param itemData any 魂石数据
function M:refreshMainItem(itemData)
    StrangeFragmentManager.SetItemData(self.debrisItem, itemData, false)
    self.txtName.text = itemData.name
end

--- 刷新洗炼面板技能列表
--- @private
function M:refreshBaptizeSkill()
    self.listPreSkill.numItems = #mPreSkillList
    if mNewSkillList ~= nil and #mNewSkillList > 0 then
        self.ctrlBaptismState.selectedIndex = 2
        self.listNewSkill.numItems = #mNewSkillList
    else
        self.ctrlBaptismState.selectedIndex = 1
    end
end

--- 魔力值更新
--- @param value number  当前魔力值
function M:refreshPowerBar(value)
    local that = self
    local max = mMaxPower
    local pro = math.min(value / max * 100, 100)

    that.txtBar.text = string.format("%d/%d", value, max)
    if not bBarAni then
        that.barPower.value = pro
        return
    end

    bBarAni = false
    local to = pro > self.barPower.value and pro or 100
    that.barPower:TweenValue(to, 0.5):OnComplete(function() 
        that.barPower.value = pro
    end)
end

--- 突破动画
---@private
function M:playBrokenAni()
    resMgr:LoadModelPrefab("UIEff/UI_shengjie_01", function(prefab)
        if self.effBrokenWrapper == nil then
            self.effBrokenWrapper = GoWrapper.New();
        end
        if self.effBroken ~= nil then
            destroyImmediate(self.effBroken);
            self.effBroken = nil
        end
        self.effBroken = newObject(prefab)
        self.effBrokenWrapper:SetWrapTarget(self.effBroken,false)
        Util.Lua_SetLocalRotationXYZ(self.effBroken.transform, 0, 0, 0)
        self.effBrokenGo:SetNativeObject(self.effBrokenWrapper)
    end)
end

--- 洗炼动画
---@private
function M:playBaptismAni()
    resMgr:LoadModelPrefab("UIEff/UI_shengjie_02", function(prefab)
        if self.effBaptismWrapper == nil then
            self.effBaptismWrapper = GoWrapper.New();
        end
        if self.effBaptism ~= nil then
            destroyImmediate(self.effBaptism);
            self.effBaptism = nil
        end
        self.effBaptism = newObject(prefab)
        self.effBaptismWrapper:SetWrapTarget(self.effBaptism,false)
        Util.Lua_SetLocalRotationXYZ(self.effBaptism.transform, 0, 0, 0)
        self.effBaptismGo:SetNativeObject(self.effBaptismWrapper)
    end)
end

--- 获取下级突破属性
--- @param itemModelId string 魂石id
--- @param level       number 魂石等级
--- @param attrId      number 属性id
--- @return number 下级属性值
function M:getNextDebrisAttr(itemModelId, level, attrId)
    local debrisCfg = dataTable.getDataTableByStringId("t_debris", tostring(itemModelId))
    if not debrisCfg or not debrisCfg.f_Next then
        return 0
    end

    local nextDebrisId  = debrisCfg.f_Next
    local debrisMajorId = nextDebrisId + level
    local debrisMajorSkillCfg = dataTable.getDataTableByStringId("t_debrismajorskill", tostring(debrisMajorId))
    if not debrisMajorSkillCfg then
        return 0
    end

    -- 等级上限
    if attrId == 0 then
        return self:getMaxLevelByDebrisId(debrisMajorSkillCfg.f_DebrisId)
    end

    -- 属性值
    if not debrisMajorSkillCfg.f_DebrisBasic then
        return 0
    end
    local debrisBasic = debrisMajorSkillCfg.f_DebrisBasic
    for i, v in ipairs(debrisBasic) do
        if v[1] == attrId then
            return v[2]
        end
    end
    return 0
end
--- 获取魂石等级上限
--- @return number 等级上限
function M:getMaxLevelByDebrisId(debrisId)
    local debrisCfg = dataTable.getDataTableByStringId("t_debris", tostring(debrisId))
    if not debrisCfg then
        return 0
    end
    return debrisCfg.f_MaxLevel or 0
end

--- 魂石职业筛选
--- @private
--- @param tag number 职业
function M:onTabProfessionChanged(tag)
    if mProfessionTag == tag then
        return
    end

    mProfessionTag = tag
    mSelectedIndex = 0
    for i, v in ipairs(self.professionbtns) do
        v.selected = (i - 1 == tag) and true or false
    end
    self:loadStoneList()
end

--- 魂石列表item
--- @private
--- @param index number  索引
--- @param obj   GObject item对象
function M:stoneItemRenderer(index, obj)
    local item = CtrlManager.GetCtrl(PanelNames.Item)
    if not item then
        return
    end
    
    local data = mItemList[index]
    if not data then
        return
    end

    StrangeFragmentManager.SetItemData(obj, data, true)
    if mSelectedItemId == data.itemId then
        obj:GetController("state").selectedIndex = 1
        self:showItemDataUI(data)
    else
        obj:GetController("state").selectedIndex = 0
    end

    obj.onClick:Clear()
    obj.onClick:Add(function() self:onSelectStoneItem(index, data.itemId, obj) end, self)
end

--- 属性列表item
--- @private
--- @param index number  索引
--- @param obj   GObject 属性item对象
function M:attrItemRenderer(index, obj)
    local txtName      = obj:GetChild("title")
    local txtCurrValue = obj:GetChild("preNum")
    local txtNextValue = obj:GetChild("num")

    local ctrlAttrType = obj:GetController("type")
    ctrlAttrType.selectedIndex = index == 1 and 3 or 0

    local attr = mAttrList[index]
    local cfg  = dataTable.getDataTableByStringId("t_attributelibrary", tostring(attr[1]))
    if cfg then
        txtName.text = cfg.f_AttributeName
    end
    if index == 1 then
        txtName.text = getLanguage("DebrisText20")
    end
    txtCurrValue.text = tostring(attr[2])
    txtNextValue.text = tostring(attr[3])
end

--- 当前技能列表item
--- @private
--- @param index number  索引
--- @param obj   GObject 技能item对象
function M:skillItemRenderer(index, obj)
    local txtUnlockTip = obj:GetChild("textUnlockTips")
    local comSkillDesc = obj:GetChild("n4")
    local ctrlState    = obj:GetController("state")
    txtUnlockTip.text  = getLanguage("DebrisText17")

    local skillData = mSkillList[index]
    if skillData.skillId == 0 then
        ctrlState.selectedIndex = 1
        return
    end

    ctrlState.selectedIndex = 0
end

--- 洗炼原技能列表item
--- @private
--- @param index number  索引
--- @param obj   GObject 原技能item对象
function M:preSkillItemRenderer(index, obj)
    local txtDesc = obj:GetChild("n4"):GetChild("textSkillType")
    local ctrlHighLevel = obj:GetController("ifHighLevel")

    local skillData = mPreSkillList[index]
    if skillData == nil then
        txtDesc.text = ""
        return
    end

    local id, value = skillData.skillId, skillData.val
    local cfg = dataTable.getDataTableByStringId("t_debrisminorskill", tostring(id))
    txtDesc.text = cfg and string.format(getLanguage(cfg.f_text), value * cfg.f_muti * 0.0001) or ""
    ctrlHighLevel.selectedIndex = self:isHighLevel(id, value) and 1 or 0
end

--- 洗炼新技能列表item
--- @private
--- @param index number  索引
--- @param obj   GObject 新技能item对象
function M:newSkillItemRenderer(index, obj)
    local txtDesc = obj:GetChild("n4"):GetChild("textSkillType")
    local ctrlHighLevel = obj:GetController("ifHighLevel")

    local skillData = mNewSkillList[index]
    if skillData == nil then
        txtDesc.text = ""
        return
    end

    local id, value = skillData.skillId, skillData.val
    local cfg = dataTable.getDataTableByStringId("t_debrisminorskill", tostring(id))
    txtDesc.text = cfg and string.format(getLanguage(cfg.f_text), value * cfg.f_muti * 0.0001) or ""
    ctrlHighLevel.selectedIndex = self:isHighLevel(id, value) and 1 or 0
end

--- 选择魂石
--- @private
--- @param index  number  所在列表索引
--- @param itemId string  道具id
--- @param obj    GObject item对象
function M:onSelectStoneItem(index, itemId, obj)
    if mSelectedIndex == index then
        return
    end
    self:setUnselectedState()

    mSelectedIndex  = index
    mSelectedItemId = itemId
    obj:GetController("state").selectedIndex = 1
    self:showItemDataUI(mItemList[index])
end

--- 取消选中状态
--- @private
function M:setUnselectedState()
    if mSelectedIndex and mSelectedIndex > 0 then
        local childIndex = self.listStone:ItemIndexToChildIndex(mSelectedIndex - 1)
        if childIndex >= 0 and childIndex < self.listStone.numChildren then
            local lastItem = self.listStone:GetChildAt(childIndex)
            if lastItem then
                lastItem:GetController("state").selectedIndex = 0
            end
        end
    end
end

--- 切换突破标签
--- @private
function M:onClickTabBroken()
    mViewType = EnumConst.DebrisViewType.Broken
    mSelectedItemId = nil
    mSelectedIndex  = nil

    self:refreshData()
    self:refreshView()
end

--- 切换洗炼标签
--- @private
function M:onClickTabBaptize()
    mViewType = EnumConst.DebrisViewType.Baptize
    mSelectedItemId = nil
    mSelectedIndex  = nil

    self:refreshData()
    self:refreshView()
end

--- 突破
--- @private
function M:onClickBroken()
    if mViewType ~= EnumConst.DebrisViewType.Broken then
        return
    end

    if not mSelectedItemId then
        UISysTips.AddMsg(string.format(getLanguage("DebrisText18"), getLanguage("Sys_Quality10")))
        return
    end

    local currTick = HelperFunc.GetServerTime()
    if currTick - mClickTick <= 1 then
        UISysTips.AddMsg(getLanguage("DebrisText27"))
        return
    end
    mClickTick = currTick

    local itemData = mItemList[mSelectedIndex]
    self:reqBrokenData(itemData)
end

--- 洗炼
--- @private
function M:onClickBaptize()
    if mViewType ~= EnumConst.DebrisViewType.Baptize then
        return
    end

    if not mSelectedItemId then
        UISysTips.AddMsg(string.format(getLanguage("DebrisText18"), getLanguage("Sys_Quality16")))
        return
    end
    
    local currTick = HelperFunc.GetServerTime()
    if currTick - mClickTick <= 1 then
        UISysTips.AddMsg(getLanguage("DebrisText27"))
        return
    end
    mClickTick = currTick

    local itemData = mItemList[mSelectedIndex]
    self:reqBaptimsData(itemData)
end

--- 自动洗炼
--- @private
function M:onClickAutoBaptize()
    if mViewType ~= EnumConst.DebrisViewType.Baptize then
        return
    end
    
    if not mSelectedItemId then
        UISysTips.AddMsg(string.format(getLanguage("DebrisText18"), getLanguage("Sys_Quality16")))
        return
    end

    local currTick = HelperFunc.GetServerTime()
    if currTick - mClickTick <= 1 then
        UISysTips.AddMsg(getLanguage("DebrisText27"))
        return
    end
    mClickTick = currTick

    local that = self
    UICommonPop.Init(122, function(flag)
        if flag then 
            local itemData = mItemList[mSelectedIndex]
            that:reqAutoBaptimsData(itemData) 
        end
    end)
end

--- 确认技能替换
--- @private
function M:onClickEnsure()
    local currTick = HelperFunc.GetServerTime()
    if currTick - mBaptizeTick <= 1.5 then
        UISysTips.AddMsg(getLanguage("DebrisText27"))
        return
    end
    mBaptizeTick = currTick

    local that = self
    local function doEnsure()
        local itemData = mItemList[mSelectedIndex]
        that:reqReplaceSkill(itemData, 1)
    end

    local isPreHigher = that:checkHigherSkill(mPreSkillList)
    local isNewHigher = that:checkHigherSkill(mNewSkillList)
    if not isPreHigher or isNewHigher then
        doEnsure()
        return
    end

    UICommonPop.Init(123, function(flag)
        if flag then doEnsure() end
    end)
end

--- 取消技能替换
---@private
function M:onClickCancel()
    local currTick = HelperFunc.GetServerTime()
    if currTick - mBaptizeTick <= 1.5 then
        UISysTips.AddMsg(getLanguage("DebrisText27"))
        return
    end
    mBaptizeTick = currTick
    
    local that = self
    local function doCancel()
        local itemData = mItemList[mSelectedIndex]
        that:reqReplaceSkill(itemData, 0)
    end

    if not that:checkHigherSkill(mNewSkillList) then
        doCancel()
        return
    end

    UICommonPop.Init(118, function(flag)
        if flag then doCancel() end
    end)
end

--- 重置魂石
--- @private
function M:onClickReset()
    self:setUnselectedState()

    mSelectedIndex  = nil
    mSelectedItemId = nil
    self:showItemDataUI(nil)
end

--- 点击品质按钮
--- @private
function M:onClickBtnLR()
    UISysTips.AddMsg(string.format(getLanguage("DebrisText19"), getLanguage("Sys_Quality10")))
end
--- 点击品质按钮
--- @private
function M:onClickBtnLRPlus()
    UISysTips.AddMsg(string.format(getLanguage("DebrisText19"), getLanguage("Sys_Quality16")))
end

--- 概率展示
--- @private
function M:onClickRatio()
    showUI(PanelNames.UIBaptismProbability)
end

--- 帮助介绍
--- @private
function M:onClickHelp()
    if mViewType == EnumConst.DebrisViewType.Broken then
        logicMgr.UIShowManager.ShowCommonTips("HelpTitle51", "HelpDes51")
    else
        logicMgr.UIShowManager.ShowCommonTips("HelpTitle52", "HelpDes52")
    end
end

--- 关闭界面
--- @private
function M:onClickClose()
    closeUI(PanelResNames.UIDebrisBaptism)
end

--- 技能出现动画
--- @private
--- @param listObj GList 列表组件
function M:playSkillItemShowAni(listObj)
    local num = listObj.numChildren
    for i = 0, num - 1 do
        local item = listObj:GetChildAt(i)
        local ctrl = item:GetTransition("Effect_Show")
        ctrl:Play(1, 0.02 * i, function() end)
    end
end
--- 技能消失动画
--- @private
--- @param listObj GList 列表组件
function M:playSkillItemHideAni(listObj)
    local num = listObj.numChildren
    for i = 0, num - 1 do
        local item = listObj:GetChildAt(i)
        local aniRemove = item:GetTransition("Effect_Remove")
        local aniReset  = item:GetTransition("reset")
        aniRemove:Play(1, 0.02 * i, function() aniReset:Play() end)
    end
end

-----------------------------------------------------------------------
--- 网络交互
-----------------------------------------------------------------------
function M:reqBrokenData(itemData)
    if not itemData then
        return
    end

    weaponHandler.ReqUpStarDebris(itemData.partnerId, itemData.itemId)
end
--- @param data DebrisDetailProtoBean 魂石数据
function M:resBrokenData(data)
    local attrList = clone(mAttrList)

    --- @type table<number, DebrisSubSkillProtoBean>
    local skillList = data.subSkills
    local itemId    = mSelectedItemId
    mSelectedItemId = nil
    mSelectedIndex  = nil
    mClickTick = HelperFunc.GetServerTime()

    self:playBrokenAni()

    if self.timerId ~= nil then
        utimer.remove(self.timerId)
        self.timerId = nil
    end
    self.timerId = utimer.delayCall(function()
        showUI(PanelNames.UIDebrisBaptismResult, itemId, attrList, skillList)

        mClickTick = 0
        self:loadStoneList()
        self:refreshCostUI()
        self:showItemDataUI(nil)
    end, 1000)
end

function M:reqBaptimsData(itemData)
    if not itemData then
        return
    end

    bBarAni = false
    weaponHandler.ReqXiLianDebris(itemData.partnerId, itemData.itemId)
end
--- @param data DebrisDetailProtoBean 魂石数据
function M:resBaptimsData(data)
    mClickTick    = HelperFunc.GetServerTime()
    mPreSkillList = data.subSkills
    mNewSkillList = data.tempSubSkills

    -- self.aniBaptism:Play()
    self:playBaptismAni()

    if self.timerId ~= nil then
        utimer.remove(self.timerId)
        self.timerId = nil
    end
    self.timerId = utimer.delayCall(function()
        mClickTick = 0
        self:refreshBaptizeSkill()
        self:refreshCostUI()
        self:playSkillItemShowAni(self.listNewSkill)
    end, 750)
end

function M:reqAutoBaptimsData(itemData)
    if not itemData then
        return
    end

    bBarAni = self.barPower.value ~= 100
    weaponHandler.ReqAutoXiLianDebris(itemData.partnerId, itemData.itemId)
end
--- @param data DebrisDetailProtoBean 魂石数据
function M:resAutoBaptimsData(data)
    mClickTick    = HelperFunc.GetServerTime()
    mPreSkillList = data.subSkills
    mNewSkillList = data.tempSubSkills

    -- self.aniBaptism:Play()
    self:playBaptismAni()

    if self.timerId ~= nil then
        utimer.remove(self.timerId)
        self.timerId = nil
    end
    self.timerId = utimer.delayCall(function()
        mClickTick = 0
        self:refreshBaptizeSkill()
        self:refreshCostUI()
        self:playSkillItemShowAni(self.listNewSkill)
    end, 750)
end

function M:reqReplaceSkill(itemData, result)
    if not itemData then
        return
    end

    self.replaceResult = result
    weaponHandler.ReqXiLianReplace(itemData.partnerId, itemData.itemId, result)
end
--- @param data DebrisDetailProtoBean 魂石数据
function M:resReplaceSkill(data)
    local that = self
    local function onResult()
        mPreSkillList = data.subSkills
        mNewSkillList = nil
        
        that.aniReset:Play()
        that:refreshBaptizeSkill()
        mBaptizeTick  = 0
    end

    -- 保存
    if self.replaceResult == 1 then
        self:playSkillItemHideAni(self.listPreSkill)
        self.aniSave:Play(onResult)
        return
    end

    -- 取消
    self.aniCancel:Play(onResult)
    self:playSkillItemHideAni(self.listNewSkill)
end

--- 魔力值
function M:reqMagicValue()
    weaponHandler.ReqMagicPower()
end
--- @param value number 魔力值
function M:resMagicValue(value)
    self:refreshPowerBar(value)
end

return M
